package com.p2p.funds.web.controller;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.activemq.command.ActiveMQTopic;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.view.RedirectView;

import com.p2p.base.annotation.LoginNeedless;
import com.p2p.base.constents.InnerAccountConsts;
import com.p2p.base.model.Money;
import com.p2p.base.model.P2PRecharge;
import com.p2p.base.service.ProducerService;
import com.p2p.base.util.MD5Util;
import com.p2p.base.web.controller.BaseController;
import com.p2p.funds.model.FundsConfig;
import com.p2p.funds.service.P2PRechargeReturnService;
import com.p2p.funds.service.P2PRechargeService;
import com.p2p.funds.web.form.ReceivePaymentModel;
import com.p2p.funds.web.form.SelectBankModel;
import com.p2p.trans.client.facade.AccountTransFacade;
import com.p2p.trans.client.model.TransInfo;
import com.p2p.trans.client.result.AccountTransResult;
import com.p2p.user.facade.UserQueryFacade;

@Controller
public class PaymentController extends BaseController {

	private static final Logger logger = LoggerFactory
			.getLogger(PaymentController.class);

	@Resource
	private P2PRechargeService p2pRechargeService;

	@Resource
	private P2PRechargeReturnService p2pRechargeReturnService;

	@Resource
	private AccountTransFacade accountTransFacade;

	@Resource
	private UserQueryFacade remoteUserQueryFacade;

	private final static String ENCRYPTIONKEY = "shengfutongSHENGFUTONGtest";

	private static DateFormat dateformat = new SimpleDateFormat(
			"yyyyMMddHHmmss");
	private String sendTime = dateformat.format(Calendar.getInstance()
			.getTime());
	private String orderNO = "1237929939";
	private String orderTime = dateformat.format(Calendar.getInstance()
			.getTime());
	@Resource
	private FundsConfig fundsConfig;
	
	@Resource
	private ProducerService producerService;
	
	@Resource
	private ActiveMQTopic rechargeSucceseDestination;

	@Deprecated
	@RequestMapping(value = "/selectBank")
	public String selectBank(ModelMap modelMap, SelectBankModel selectBankModel) {
		/** 去生成订单信息，订单号转入到selectBank */
		selectBankModel
				.setOrderNo(String.valueOf(Math.round(Math.random() * 90000000 + 10000000)));
		selectBankModel.setOrderTime(dateformat.format(Calendar.getInstance()
				.getTime()));
		modelMap.addAttribute("selectBankModel", selectBankModel);
		return "views/selectBank";
	}

	@RequestMapping(value = "/recharge/applyPayment")
	public RedirectView applyPayment(@RequestParam Long id,
			ModelMap modelMap, HttpServletRequest request,
			HttpServletResponse response) {

		P2PRecharge p2pRecharge = p2pRechargeService.findP2PRechargeById(id);

		String orderNo = p2pRecharge.getId().toString();

		StringBuilder sb = new StringBuilder();
		Double inputOrderAmount = new Double(p2pRecharge.getMoney().getCent()/100d);
		sb.append(fundsConfig.getName());
		sb.append(fundsConfig.getVersion());
		sb.append(fundsConfig.getCharset());
		sb.append(fundsConfig.getMsgSender());
		sb.append(sendTime);
		sb.append(orderNo);

		sb.append(inputOrderAmount);
		sb.append(orderTime);
		sb.append(fundsConfig.getPayType());
		sb.append(fundsConfig.getPayChannel());
		sb.append(p2pRecharge.getType());
		sb.append(fundsConfig.getPageUrl());
		sb.append(fundsConfig.getBackUrl());
		sb.append(fundsConfig.getNotifyUrl());
		sb.append(fundsConfig.getProductName());
		sb.append(fundsConfig.getBuyerContact());
		sb.append(fundsConfig.getBuyerIp());
		sb.append(fundsConfig.getExt());
		sb.append(fundsConfig.getSignType());
		sb.append(ENCRYPTIONKEY);
		System.out.println("sendstr=" + sb.toString());
		String MD5Result = MD5Util.md5(sb.toString()).toUpperCase();

		modelMap.addAttribute("Name", fundsConfig.getName());
		modelMap.addAttribute("Version", fundsConfig.getVersion());
		modelMap.addAttribute("Charset", fundsConfig.getCharset());
		modelMap.addAttribute("MsgSender", fundsConfig.getMsgSender());
		modelMap.addAttribute("SendTime", sendTime);
		modelMap.addAttribute("OrderNo", orderNo);
		modelMap.addAttribute("OrderAmount", inputOrderAmount);
		modelMap.addAttribute("OrderTime", orderTime);
		modelMap.addAttribute("PayType", fundsConfig.getPayType());
		modelMap.addAttribute("PayChannel", fundsConfig.getPayChannel());
		modelMap.addAttribute("InstCode", p2pRecharge.getType());
		modelMap.addAttribute("NotifyUrl", fundsConfig.getNotifyUrl());
		modelMap.addAttribute("PageUrl", fundsConfig.getPageUrl());
		modelMap.addAttribute("BackUrl", fundsConfig.getBackUrl());
		modelMap.addAttribute("ProductName", fundsConfig.getProductName());
		modelMap.addAttribute("BuyerContact", fundsConfig.getBuyerContact());
		modelMap.addAttribute("BuyerIp", fundsConfig.getBuyerIp());
		modelMap.addAttribute("Ext1", fundsConfig.getExt());
		modelMap.addAttribute("SignType", fundsConfig.getSignType());
		modelMap.addAttribute("SignMsg", MD5Result);
		return new RedirectView(
				"https://mas.sdo.com/web-acquire-channel/cashier.htm", true,
				false, true);
	}

	@LoginNeedless
	@RequestMapping(value = "/receivePayment", method = RequestMethod.POST)
	public void receivePayment(HttpServletRequest request,
			HttpServletResponse response,
			ReceivePaymentModel receivePaymentModel) {
		System.out.println("receivePayment  xxxx");
		StringBuilder sb = new StringBuilder();

		String Name = receivePaymentModel.getName();
		sb.append(Name);
		String Version = receivePaymentModel.getVersion();
		sb.append(Version);
		String Charset = receivePaymentModel.getCharset();
		sb.append(Charset);
		String TraceNo = receivePaymentModel.getTraceNo();
		sb.append(TraceNo);
		String MsgSender = receivePaymentModel.getMsgSender();
		sb.append(MsgSender);
		String SendTime = receivePaymentModel.getSendTime();
		sb.append(SendTime);
		String InstCode = receivePaymentModel.getInstCode();
		sb.append(InstCode);
		String OrderNo = receivePaymentModel.getOrderNo();
		sb.append(OrderNo);
		String OrderAmount = receivePaymentModel.getOrderAmount();
		sb.append(OrderAmount);
		String TransNo = receivePaymentModel.getTransNo();
		sb.append(TransNo);
		String TransAmount = receivePaymentModel.getTransAmount();
		sb.append(TransAmount);
		String TranStatus = receivePaymentModel.getTranStatus();
		sb.append(TranStatus);
		String TransType = receivePaymentModel.getTransType();
		sb.append(TransType);
		String TransTime = receivePaymentModel.getTransTime();
		sb.append(TransTime);
		String MerchantNo = receivePaymentModel.getMerchantNo();
		sb.append(MerchantNo);
		String ErrorCode = receivePaymentModel.getErrorCode();
		sb.append(ErrorCode);
		String ErrorMsg = receivePaymentModel.getErrorMsg();
		sb.append(ErrorMsg);
		String Ext1 = receivePaymentModel.getExt1();
		sb.append(Ext1);
		String signType = receivePaymentModel.getSignType();
		sb.append(signType);
		//String BankSerialNo = receivePaymentModel.getBankSerialNo();
		sb.append(ENCRYPTIONKEY);
		System.out.println("str=" + sb.toString());

		String SignMsg = receivePaymentModel.getSignMsg();
		System.out.println("SignMsg=" + SignMsg);

		String md5Result = MD5Util.md5(sb.toString()).toUpperCase();
		System.out.println("md5Result=" + md5Result);
		System.out.println("OrderNo=" + OrderNo);
		// 计算结果串与返串相通，则做进一步处理
		if (SignMsg.equals(md5Result)) {
			Long rechargeId = Long.valueOf(OrderNo);

			P2PRecharge p2pRecharge = p2pRechargeService
					.findP2PRechargeById(rechargeId);
			// 金额的比较
			if (p2pRecharge.getMoney().equals(Double.valueOf(OrderAmount))) {
				p2pRecharge.setStatus(P2PRecharge.Status.SUCCESS.getStatus());
				p2pRecharge.setOutTransNo(TransNo);
				p2pRecharge.setUpTime(Calendar.getInstance().getTimeInMillis());
				p2pRecharge.setOkTime(Calendar.getInstance().getTimeInMillis());
				p2pRecharge.setUpIp(getRemoteIp(request));
				p2pRechargeService.updateP2PRecharge(p2pRecharge);
				/*
				 * P2PRechargeReturn p2pRechargeReturn = new
				 * P2PRechargeReturn();
				 * p2pRechargeReturn.setRid(Long.valueOf(TransNo));
				 * p2pRechargeReturn
				 * .setUpTime(Calendar.getInstance().getTimeInMillis());
				 * p2pRechargeReturn
				 * .setStatus(P2PRechargeReturn.Status.HIDDEN.getStatus());
				 * p2pRechargeReturnService
				 * .saveP2PRechargeReturn(p2pRechargeReturn);
				 */

				String userAccountNo = p2pRecharge.getTradeAccount();

				if (StringUtils.isNoneBlank(userAccountNo)) {
					TransInfo transInfo = new TransInfo();

					// 充值账号
					transInfo.setTransAccountIn(userAccountNo);
					// 总帐总帐账号
					transInfo.setTransAccountOut(InnerAccountConsts.innerTotalAccountNo);
					/*Long money = (long) (p2pRecharge.getMoney() * 100);

					Money m = new Money();
					m.setCent(money);*/

					// 充值金额
					transInfo.setTransAmount(p2pRecharge.getMoney());
					// 充值做帐
					transInfo.setTransOutOrderNo(OrderNo);
					AccountTransResult result = accountTransFacade
							.doDeposit(transInfo);
					if (!result.isSuccess()) {
						logger.error("accountTransFacade.doDeposit error,code="
								+ result.getResultCode());
					}else{
						this.sendNotify(p2pRecharge);
					}
				} else {
					logger.error("user accountNo not exit");
				}

				returnMessage(response, "OK");
			}
		}
	}

	@RequestMapping("/home/bizError")
	public String bizError(Model model, String errorMessage) {
		model.addAttribute("errorMessage", errorMessage);
		return "views/bizError";
	}

	// TODO 测试用的
	@RequestMapping(value = "/testReceivePayment")
	public String testReceivePayment() {
		return "views/testReceivePayment";
	}

	// TODO 测试用的
	@RequestMapping("/sendPayment")
	public String sendPayment(@RequestParam String orderAmount,
			@RequestParam String instCode, ModelMap modelMap) throws Exception {
		StringBuilder sb = new StringBuilder();
		sb.append(fundsConfig.getName());
		sb.append(fundsConfig.getVersion());
		sb.append(fundsConfig.getCharset());
		sb.append(fundsConfig.getMsgSender());
		sb.append(sendTime);
		sb.append(orderNO);
		sb.append(orderAmount);
		sb.append(orderTime);
		sb.append(fundsConfig.getPayType());
		sb.append(fundsConfig.getPayChannel());
		sb.append(instCode);
		sb.append(fundsConfig.getPageUrl());
		sb.append(fundsConfig.getBackUrl());
		sb.append(fundsConfig.getNotifyUrl());
		sb.append(fundsConfig.getProductName());
		sb.append(fundsConfig.getBuyerContact());
		sb.append(fundsConfig.getBuyerIp());
		sb.append(fundsConfig.getExt());
		sb.append(fundsConfig.getSignType());
		sb.append(ENCRYPTIONKEY);

		String MD5Result = MD5Util.md5(sb.toString()).toUpperCase();

		modelMap.addAttribute("name", fundsConfig.getName());
		modelMap.addAttribute("version", fundsConfig.getVersion());
		modelMap.addAttribute("charset", fundsConfig.getCharset());
		modelMap.addAttribute("msgSender", fundsConfig.getMsgSender());
		modelMap.addAttribute("sendTime", sendTime);
		modelMap.addAttribute("orderNO", orderNO);
		modelMap.addAttribute("orderAmount", orderAmount);
		modelMap.addAttribute("orderTime", orderTime);
		modelMap.addAttribute("payType", fundsConfig.getPayType());
		modelMap.addAttribute("payChannel", fundsConfig.getPayChannel());
		modelMap.addAttribute("instCode", instCode);
		modelMap.addAttribute("notifyUrl", fundsConfig.getNotifyUrl());
		modelMap.addAttribute("pageUrl", fundsConfig.getPageUrl());
		modelMap.addAttribute("backUrl", fundsConfig.getBackUrl());
		modelMap.addAttribute("productName", fundsConfig.getProductName());
		modelMap.addAttribute("buyerContact", fundsConfig.getBuyerContact());
		modelMap.addAttribute("buyerIp", fundsConfig.getBuyerIp());
		modelMap.addAttribute("ext", fundsConfig.getExt());
		modelMap.addAttribute("signType", fundsConfig.getSignType());
		modelMap.addAttribute("SignMsg", MD5Result);

		return "views/sendPayment";
	}

	// TODO delete test
	@RequestMapping(value = "/testReceive")
	public String testReceive(HttpServletResponse response,
			ReceivePaymentModel receivePaymentModel, ModelMap map) {
		map.addAttribute("test", "Test");
		return "redirect:http://www.baidu.com";
		/*
		 * logger.debug(receivePaymentModel.getName());
		 * System.out.println("dke dli ed lie id i " +
		 * receivePaymentModel.getName()); returnMessage(response, "OK");
		 */
	}
	
	private void sendNotify(P2PRecharge p2pRecharge){
		this.producerService.sendMessage(rechargeSucceseDestination, p2pRecharge);
	}
}
